package upgrade

import (
	"context"
	"strconv"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/sagoo-cloud/sagooiot/api/v1/upgrade"
	"github.com/sagoo-cloud/sagooiot/internal/dao"
	"github.com/sagoo-cloud/sagooiot/internal/model"
	"github.com/sagoo-cloud/sagooiot/internal/model/entity"
	"github.com/sagoo-cloud/sagooiot/internal/service"
)

type sUpgradeHttp struct{}

func sUpgradeHttpNew() *sUpgradeHttp {
	return &sUpgradeHttp{}
}

func init() {
	service.RegisterUpgradeHttp(sUpgradeHttpNew())
}

// WriteUpgradeInfo 更新升级进度
func (s *sUpgradeHttp) WriteUpgradeInfo(ctx context.Context, in *upgrade.WriteOtaInfoReq) (err error) {
	var (
		device   entity.DevDevice
		product  entity.DevProduct
		detail   entity.DevOtaDetail
		strategy entity.DevOtaStrategy
	)
	err = dao.DevDevice.Ctx(ctx).Where(dao.DevDevice.Columns().Key, in.Params.DeviceKey).Scan(&device)
	if err != nil {
		return
	}
	err = dao.DevProduct.Ctx(ctx).Where(dao.DevProduct.Columns().Id, device.ProductId).Scan(&product)
	if err != nil {
		return
	}
	err = dao.DevOtaStrategy.Ctx(ctx).Where(dao.DevOtaStrategy.Columns().Id, in.Params.Strategy).
		Scan(&strategy)
	if err != nil {
		return
	}

	total, err := dao.DevOtaDetail.Ctx(ctx).Where(dao.DevOtaDetail.Columns().DeviceId, device.Id).
		Where(dao.DevOtaDetail.Columns().StrategyId, strategy.Id).Count()
	if err != nil {
		g.Log().Errorf(ctx, "%v+", err)
		return
	}
	if total > 0 {
		up := g.MapAnyAny{"step": in.Params.Step, "status": 2}
		if in.Params.Step < 0 {
			up["status"] = 4
			up["fail"] = in.Params.Step
		}
		dao.DevOtaDetail.Ctx(ctx).Where(dao.DevOtaDetail.Columns().DeviceId, device.Id).
			Where(dao.DevOtaDetail.Columns().StrategyId, in.Params.Strategy).
			Update(up)
	} else {
		detail.DeviceId = int(device.Id)
		detail.Step = strconv.Itoa(in.Params.Step)
		detail.StrategyId = strategy.Id
		detail.Status = 2
		_, err = dao.DevOtaDetail.Ctx(ctx).Insert(detail)
	}

	return
}

// 更新升级结果
func (s *sUpgradeHttp) WriteUpgradeResult(ctx context.Context, in *upgrade.WriteOtaResultReq) (err error) {
	var (
		device entity.DevDevice
	)
	err = dao.DevDevice.Ctx(ctx).Where(dao.DevDevice.Columns().Key, in.Params.DeviceKey).Scan(&device)
	if err != nil {
		return
	}
	service.UpgradeDevOtaDetail().RecordUpgradeResult(ctx, int(device.Id), in.Params.Strategy, in.Params.Version)

	return
}

// GetUpgradeInfo 获取升级信息
func (s *sUpgradeHttp) GetUpgradeInfo(ctx context.Context, in *upgrade.GetOtaInfoReq) (res *upgrade.GetOtaInfoRes, err error) {

	info := new(model.UpgradeHttpInfo)
	err = dao.DevOtaStrategy.Ctx(ctx).InnerJoin("dev_ota_fireware ", "dev_ota_strategy.dev_ota_fireware_id = dev_ota_fireware.id").
		InnerJoin("dev_product  ", " dev_product.id = dev_ota_fireware.product_id ").
		InnerJoin("dev_device", " dev_product.id = dev_device.product_id  ").
		Where("dev_device.key = ? and dev_ota_strategy.active = 1", in.DeviceKey).
		Fields("dev_ota_fireware.*,dev_ota_strategy.id strategy").OrderDesc("dev_ota_fireware.created_at").Limit(1).Scan(&info)
	if err != nil {
		return
	}
	res = new(upgrade.GetOtaInfoRes)

	res.ExtData = g.MapStrAny{"strategy": info.Strategy}
	res.Url = info.OssUrl
	res.Version = info.Version // 上传的升级包版本号
	res.Module = info.Module
	res.Sign = info.Sign
	res.SignMethod = info.Are

	return
}
